package com.netty.simple;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;

/*
说明
1. 我们自定义一个Handler 需要继承netty 规定好的某个HandlerAdapter(规范)
2. 这时我们自定义一个Handler , 才能称为一个handler
 */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    //读取数据实际(这里我们可以读取客户端发送的消息)
    /*
    1. ChannelHandlerContext ctx:上下文对象, 含有 管道pipeline , 通道channel, 地址
    2. Object msg: 就是客户端发送的数据 默认Object
     */    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         //比如这里我们有一个非常耗时长的业务-> 异步执行 -> 提交该channel 对应的NIOEventLoop 的 taskQueue中
        //Thread.sleep(10*1000);//休眠10秒
        //ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端,阻塞了10秒", CharsetUtil.UTF_8));
        //解决方案1 用户程序自定义的普通任务
        /*ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(10*1000);
                    ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端,阻塞了10秒,异步执行!", CharsetUtil.UTF_8));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });*/
        //解决方案2 : 用户自定义定时任务 -》 该任务是提交到 scheduleTaskQueue中
        System.out.println(ctx.channel().hashCode()+">>>>>>>");
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端! 采用scheduleTaskQueue方式", CharsetUtil.UTF_8));
            }
        }, 5, TimeUnit.SECONDS);//定时5秒
        System.out.println("继续执行!");

        //System.out.println("当前工作线程是: "+Thread.currentThread().getName());
        //System.out.println("server ctx = "+ctx);
        //将 msg 转成一个 ByteBuf
        //ByteBuf 是 Netty 提供的，不是 NIO 的 ByteBuffer.
        //ByteBuf buf = (ByteBuf)msg;
        //System.out.println("客户端发送的消息是:"+buf.toString(CharsetUtil.UTF_8));
        //System.out.println("客户端的地址是:"+ctx.channel().remoteAddress());
        Channel channel = ctx.channel();
        ChannelPipeline pipeline = ctx.pipeline(); //本质是一个双向链接, 出站入站
    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //writeAndFlush 是 write + flush
        //将数据写入到缓存，并刷新
        //一般讲，我们对这个发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello 客户端!",CharsetUtil.UTF_8));
    }

    //处理异常, 一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
        //ctx.close();
    }
}
